<template>
    <view>
        <view class="echarts" :id="option.id" :prop="option" :change:prop="echarts.update" @click="echarts.onClick"></view>
    </view>
</template>
<script>
    export default { 
        name: 'Echarts',
        props: { 
            option: { 
                type: Object,
                required: true
            }
        },
        created() { 
            // 设置随机数id
            let t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
            let len = t.length
            let id = ''
            for (let i = 0; i < 32; i++) { 
                id += t.charAt(Math.floor(Math.random() * len))
            }
						console.log(this.option);
            this.option.id = id
        },
        methods: { 
            /** * renderjs内的点击事件，回调到父组件 * @param {Object} params */
            onViewClick(params) { 
                this.$emit('click', params)
            }
        }
    }
</script>
<script module="echarts" lang="renderjs">
    import * as echarts from '@/utils/echarts.min(5.4.2).js';
    export default { 
        data() { 
            return { 
                chart: null,
                clickData: null // echarts点击事件的值
            }
        },
        mounted() { 
            this.init();
        },
        methods: { 
            /** * 初始化echarts */
            init() { 
                // 根据id初始化图表
                this.chart = echarts.init(document.getElementById(this.option.id))
                this.update(this.option)
                // echarts的点击事件
                this.chart.on('click', params => { 
                    // 把点击事件的数据缓存下来
                    this.clickData = params
                })
            },
            /** * 点击事件，可传递到外部 * @param {Object} event * @param {Object} instance */
            onClick(event, instance) { 
                if (this.clickData) { 
                    // 把echarts点击事件相关的值传递到renderjs外
                    instance.callMethod('onViewClick', { 
                        value: this.clickData.data,
                        name: this.clickData.name,
                        seriesName: this.clickData.seriesName
                    })
                    // 上次点击数据置空
                    this.clickData = null
                }
            },
            /** * 监测数据更新 * @param {Object} option */
            update(option) { 
                if (this.chart) { 
                    // 因App端，回调函数无法从renderjs外传递，故在此自定义设置相关回调函数
                    if (option) { 
                        // tooltip
                        if (option.tooltip) { 
                            // 判断是否设置tooltip的位置
                            if (option.tooltip.positionStatus) { 
                                option.tooltip.position = this.tooltipPosition()
                            }
                            // 判断是否格式化tooltip
                            if (option.tooltip.formatterStatus) { 
                                option.tooltip.formatter = this.tooltipFormatter(option.tooltip.formatterUnit, option.tooltip.formatFloat2, option.tooltip.formatThousands)
                            }
                        }
                    }
                    // 设置新的option
                    this.chart.setOption(option, option.notMerge)
                }
            },
            /** * 设置tooltip的位置，防止超出画布 */
            tooltipPosition() { 
                return (point, params, dom, rect, size) => { 
                    // 其中point为当前鼠标的位置，size中有两个属性：viewSize和contentSize，分别为外层div和tooltip提示框的大小
                    let x = point[0]
                    let y = point[1]
                    let viewWidth = size.viewSize[0]
                    let viewHeight = size.viewSize[1]
                    let boxWidth = size.contentSize[0]
                    let boxHeight = size.contentSize[1]
                    let posX = 0 // x坐标位置
                    let posY = 0 // y坐标位置
                    if (x >= boxWidth) {  // 左边放的下
                        posX = x - boxWidth - 1
                    }
                    if (y >= boxHeight) {  // 上边放的下
                        posY = y - boxHeight - 1
                    }
                    return [posX, posY]
                }
            },
            /** * tooltip格式化 * @param {Object} unit 数值后的单位 * @param {Object} formatFloat2 是否保留两位小数 * @param {Object} formatThousands 是否添加千分位 */
            tooltipFormatter(unit, formatFloat2, formatThousands) { 
                return params => { 
                    let result = ''
                    unit = unit ? unit : ''
                    for (let i in params) { 
                        if (i == 0) { 
                            result += params[i].axisValueLabel
                        }
                        let value = '--'
                        if (params[i].data !== null) { 
                            value = params[i].data
                            // 保留两位小数
                            if (formatFloat2) { 
                                value = this.formatFloat2(value)
                            }
                            // 添加千分位
                            if (formatThousands) { 
                                value = this.formatThousands(value)
                            }
                        }
                        // #ifdef H5
                        result += '\n' + params[i].seriesName + '：' + value + ' ' + unit
                        // #endif
                        // #ifdef APP-PLUS
                        result += '<br/>' + params[i].marker + params[i].seriesName + '：' + value + ' ' + unit
                        // #endif
                    }
                    return result
                }
            },
            /** * 保留两位小数 * @param {Object} value */
            formatFloat2(value) { 
                let temp = Math.round(parseFloat(value) * 100) / 100
                let xsd = temp.toString().split('.')
                if (xsd.length === 1) { 
                    temp = (isNaN(temp) ? '0' : temp.toString()) + '.00'
                    return temp
                }
                if (xsd.length > 1) { 
                    if (xsd[1].length < 2) { 
                        temp = temp.toString() + '0'
                    }
                    return temp
                }
            },
            /** * 添加千分位 * @param {Object} value */
            formatThousands(value) { 
                if (value === undefined || value === null) { 
                    value = ''
                }
                if (!isNaN(value)) { 
                    value = value + ''
                }
                let re = /\d{1,3}(?=(\d{3})+$)/g
                let n1 = value.replace(/^(\d+)((\.\d+)?)$/, function(s, s1, s2) { 
                    return s1.replace(re, '$&,') + s2
                })
                return n1
            }
        }
    }
</script>
<style lang="scss" scoped>
    .echarts { 
        width: 100%;
        height: 100%;
    }
</style>